spravne uklizeni pameti

Otázka od: david.kopecek@hacktrack.com

9. 11. 2004 16:35

Zdravim

chtel bych par profesionalu pozadat o radu..
jak spravne ve funkci ci procedure po sobe cistit obsazenou pamet..

vim ze na tstringlist je nejlepsi free. ale co dalsi veci.. arraye of
cosi nebo stringy kde jsem natahl cca 2 kila dat...

--
S pozdravem,
 david
 david.kopecek@hacktrack.com



Odpovedá: Petr Brant

9. 11. 2004 16:57

Zalezi na tom, jak tu pamet alokujes. Pokud napriklad

var a: string;
     b: array[1..10000] of integer;

a podobne, kdy je kompilator schopen urcit velikost alokovane pameti (u
stringu to umi take), nemusis se o uvolnovani starat, to se provadi
automaticky. Pokud ale alokujes pamet sam, napriklad

O: array of TYourObject;
O:= TYourObject.Create;
O:= GetMem(p, 20000);
O:= new(OBj)

je treba pamet uvolnit rucne (O:= nil, O.Free, FreeMem(O), Dispose(Obj) ).
Pozor ale na to, pokud tvuj objekt obsahuje dalsi objekty. Ty se musi
nejprve uvolnit (zpravidla v destruktoru, je-li k dispozici) anebo rucne,
napriklad pokud se jedna o prvky TList, viz ukazka ze skutecneho kodu:

procedure TAllowances.ClearDataList;
var i: integer;
begin
 for i:= 0 to FDataList.Count - 1 do
  TClPosData(FDataList.Items[i]).Free; --- uvolneni jednotlivych prvku
seznamu
 FDataList.Clear;
end;

... a samotne uvolneni objektu FDataList:

destructor TAllowances.Destroy;
begin
 inherited;
...
 ClearDataList;
 FDataList.Free;
...
end;

Pro TStringList neni podobna konstrukce nutna, protoze Delphi "vedi", kolik
pameti se pri praci s tim seznamem naalokovalo pameti, takze uvolneni je
automaticke.
No a pokud si nejsi jisty, pouzij MemProof a ten je schopen zjistit, jestli
nekde neni neco zapomenuteho. Osvedcil se mi postup, kdy bezprostredne po
napsani kodu alokujiciho pamet vzapeti pisu kod, ktery bude pamet uvolnovat.

RNDr. Petr Brant [brant@dcomm.cz]
http://brant.wz.cz <http://brant.wz.cz>


> chtel bych par profesionalu pozadat o radu..
> jak spravne ve funkci ci procedure po sobe cistit obsazenou pamet..
>
> vim ze na tstringlist je nejlepsi free. ale co dalsi veci.. arraye of
> cosi nebo stringy kde jsem natahl cca 2 kila dat...
>

Odpovedá: Slavomir Skopalik

9. 11. 2004 17:29

> Zalezi na tom, jak tu pamet alokujes. Pokud napriklad
>
> var a: string;
> b: array[1..10000] of integer;

Tahle pamet se nealokuje klasicky,
ale pouze vyhradi na stacku volane funkce.

>
> a podobne, kdy je kompilator schopen urcit velikost alokovane
> pameti (u stringu to umi take), nemusis se o uvolnovani
> starat, to se provadi automaticky. Pokud ale alokujes pamet
> sam, napriklad
>
> O: array of TYourObject;

Tuto pamet uvolnuje automaticky compiler na zaklade pocitani referenci.
Vrele doporucuji se o tuto pamet nestarat.
To same plati pro stringy, ale pozor, ne pro PCHAR.

Je treba si uvedomit, ze string; a array of neco; je uplne to same !

Obecne plati, pokud nic rucne nevytvarim, tak to taky neuvolnuji.

> procedure TAllowances.ClearDataList;
> var i: integer;
> begin
> for i:= 0 to FDataList.Count - 1 do
> TClPosData(FDataList.Items[i]).Free; --- uvolneni
> jednotlivych prvku seznamu FDataList.Clear; end;
>
> ... a samotne uvolneni objektu FDataList:
>
> destructor TAllowances.Destroy;
> begin
> inherited;
> ...
> ClearDataList;
> FDataList.Free;
> ...
> end;

Zde byla pouzita nevhodna trida pro uchovani seznamu objektu.
Vhodnejsi je pouzit TObjectList.
Ten pak umi i vlozene objekty vlastnit a tudiz se postara o jejich
uvolneni.


>
> Pro TStringList neni podobna konstrukce nutna, protoze Delphi
> "vedi", kolik pameti se pri praci s tim seznamem naalokovalo
> pameti, takze uvolneni je automaticke.

Tohle neni specialni pripad TStringListu, ale vsech typovyh listu.
Napriklad Tcollection, Tcomponent, ...

> No a pokud si nejsi jisty, pouzij MemProof a ten je schopen
> zjistit, jestli nekde neni neco zapomenuteho. Osvedcil se mi
> postup, kdy bezprostredne po napsani kodu alokujiciho pamet
> vzapeti pisu kod, ktery bude pamet uvolnovat.

Dobry indikator je GetHeapStatus.TotalAllocated;

 Slavek